package com.song.tools.mvc.validator;

import com.song.tools.core.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

/**
 * 验证器链类，实现了ParamValidator接口，用于通过链式调用多个验证器来验证参数。
 * 这种链式验证器的设计模式允许灵活地组合验证逻辑，而不需要在调用方进行复杂的条件判断。
 * <p>
 * 例如：
 * <pre>
 *     <code>
 *       public ValidationResult validate() {
 *         ValidatorChain validatorChain = new ValidatorChain();
 *         validatorChain.add(() -> new StrNotBlankValidator("code").validate(this::getCode));
 *         validatorChain.add(() -> new StrNotBlankValidator("name").validate(this::getName));
 *         return validatorChain.validate();
 *     }
 *     </code>
 * </pre>
 *
 * @author song tools
 * @since 2024-06-21
 */
public class ValidatorChain {
    private final List<Supplier<ValidationResult>> resultSuppliers;

    public ValidatorChain() {
        resultSuppliers = new ArrayList<>();
    }

    public ValidatorChain add(Supplier<ValidationResult> resultSupplier) {
        resultSuppliers.add(resultSupplier);
        return this;
    }

    public ValidationResult validate() {
        for (Supplier<ValidationResult> resultSupplier : resultSuppliers) {
            ValidationResult validationResult = resultSupplier.get();
            if (!validationResult.isValid()) {
                return validationResult;
            }
        }

        return new ValidationResult(true, null);
    }

    public ValidationResult validateAll() {
        List<String> errorMessages = new ArrayList<>();
        for (Supplier<ValidationResult> resultSupplier : resultSuppliers) {
            ValidationResult validationResult = resultSupplier.get();
            if (!validationResult.isValid()) {
                errorMessages.add(validationResult.getErrorMessage());
            }
        }

        if(ObjectUtils.isEmpty(errorMessages)) {
            return new ValidationResult(true, null);
        }
        return ValidationResult.fail(String.join(";", errorMessages));
    }
}
